home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / gfx / show / jpegAGAsrc21.lha / jpegAGAsrc / jpegAGA / jpegAGA.c < prev    next >
C/C++ Source or Header  |  1995-02-04  |  20KB  |  747 lines

  1. /* jpegAGA 2.1 written by Günther Röhrich */
  2.  
  3. #include <workbench/startup.h>
  4.  
  5. #ifndef __GNUC__
  6. #include <pragmas/dos_pragmas.h>
  7. #include <clib/dos_protos.h>
  8. #else
  9. #include <inline/dos.h>
  10. #endif
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14.  
  15. /*
  16.  * Include file for users of JPEG library.
  17.  * You will need to have included system headers that define at least
  18.  * the typedefs FILE and size_t before you can include jpeglib.h.
  19.  * (stdio.h is sufficient on ANSI-conforming systems.)
  20.  * You may also wish to include "jerror.h".
  21.  */
  22.  
  23. #include "jpeglib.h"
  24. #include "jerror.h"
  25. #include "myerror.h"
  26. #define JMAKE_MSG_TABLE
  27. #include "myerror.h" /* create the message string table */
  28.  
  29. /*
  30.  * <setjmp.h> is used for the optional error recovery mechanism shown in
  31.  * the second part of the example.
  32.  */
  33.  
  34. #include <setjmp.h>
  35. #include <signal.h>
  36. #include <string.h>
  37.  
  38.  
  39. extern void Amiga_jpeg_stdio_src (j_decompress_ptr cinfo, BPTR infile);
  40.  
  41. #define HAM8 1
  42.  
  43. /* #define DEBUGFILE */ /* write a ppm file for debugging */
  44.  
  45. #ifdef __GNUC__
  46. #define MYSTRCMP strcasecmp
  47. #define MYSTRNCMP strncasecmp
  48. #else
  49. #define MYSTRCMP strcmp
  50. #define MYSTRNCMP strncmp
  51. #endif
  52.  
  53. #define MAXFILES 500
  54.  
  55. char  *ver = "\0$VER: jpegAGA 2.1 (4.2.95)";
  56.  
  57. #ifdef __GNUC__
  58. char __stdiowin[]="CON:30/12/600/80/jpegAGA 2.1";
  59. #endif
  60.  
  61. /* Flags */
  62.  
  63. struct WBFlags
  64. {
  65.  int scale;
  66.  short VGAenable;
  67.  short SUPER72enable;
  68.  short SMRenable;
  69.  short GrayEnable;
  70.  short NoSmooth;
  71.  short DCTFast;
  72.  short ScaleFit;
  73. };
  74.  
  75. struct WBFlags WBFlags =
  76. {
  77.  1, 0, 0, 0, 0, 0, 0, 0
  78. };
  79.  
  80. struct WBFlags OldFlags;
  81.  
  82. short SMR_HAM;
  83. short WBFiles=0;
  84. short DoNotWait=0;
  85. short finish=0;
  86. static short ButtonPressed=0;
  87.  
  88. BPTR olddir=0;
  89. int NumPictures=0;
  90. struct WBArg *wb_arg=NULL;
  91. char *PicArray[MAXFILES];
  92. unsigned long SMR_DisplayID = 0;
  93. unsigned long *ScreenColorTable=NULL;
  94.  
  95.  
  96. static unsigned long Mode=0;
  97. static char *MapFileName=NULL;
  98. static char *MapDirName=NULL;
  99. static BPTR infile=0;
  100. static BPTR ColorMapFile = 0;
  101.  
  102. volatile int PictureNr;
  103.  
  104. extern void FillNameBuffer(char *pattern);
  105. extern void ParseToolTypes(struct WBArg *wbarg, int initial);
  106. extern int InitDisplay(int cols, int rows, unsigned long Mode, int NumPlanes);
  107. extern void CloseDisplay(void);
  108. extern void DisplayRow(JSAMPROW buffer, int cols);
  109. extern int CheckButton(void);
  110. extern void FinalWait(void);
  111. extern void FlipScreen(void);
  112. extern int ChooseScreenMode(int grayscale, char *title);
  113. extern void ChooseFiles(void);
  114. extern int FindScaleFit(JDIMENSION width, JDIMENSION height, unsigned long Mode);
  115. extern unsigned long my_screen[2];
  116. extern unsigned long ScaleFitDisplayID;
  117. JSAMPROW OutputBuffer=NULL;
  118.  
  119. extern void EncodeHAM8(JSAMPROW orig, JSAMPROW yham, int xsize);
  120. unsigned short Mult_Table[2*256];
  121. jmp_buf setjmp_buffer;
  122.  
  123. /* NOTE: this array is in brgbrg order */
  124.  
  125. char *ColorCache=NULL;
  126. unsigned char FixedColorTable[64*3] =
  127.  { 0, 0, 0,  4, 4, 4,  8, 8, 8, 12,12,12,   
  128.   16,16,16, 20,20,20, 24,24,24, 28,28,28,  /* 16 colors */
  129.   32,32,32, 36,36,36, 41,41,41, 46,46,46,
  130.   51,51,51, 55,55,55, 59,59,59, 63,63,63,
  131.  
  132.  
  133.                       17,17,39, 17,17,55, /* 13 colors */ 
  134.   17,29,17,           17,29,39, 17,29,55, 
  135.   17,39,17, 17,39,29, 17,39,39, 17,39,55,
  136.   17,55,17, 17,55,39, 17,55,39, 17,55,55,
  137.  
  138.  
  139.             29,17,29, 29,17,39, 29,17,55, /* 11 colors */
  140.                                 29,29,55,
  141.   29,39,17, 29,39,29,           29,39,55,
  142.   29,55,17, 29,55,29, 29,55,39, 29,55,55,
  143.  
  144.  
  145.   39,17,17, 39,17,29, 39,17,39, 39,17,55, /* 12 colors */
  146.   39,29,17, 39,29,29,           39,29,55,
  147.   39,39,17, 39,39,29,          
  148.   39,55,17, 39,55,29,  
  149.  
  150.   
  151.   55,17,17, 55,17,29, 55,17,39, 55,17,55, /* 13 colors */
  152.   55,29,27, 55,29,29, 55,29,39, 55,29,55,
  153.   55,39,17, 55,39,29, 55,39,39, 
  154.   55,55,17, 55,55,29
  155. };
  156.  
  157. unsigned char ColorTable[64*3];
  158.  
  159.  
  160.  
  161. METHODDEF void
  162. my_error_exit (j_common_ptr cinfo)
  163. {
  164.  /* Always display the message. */
  165.  if(cinfo->err->msg_code != JWRN_JPEGAGA_STOPPED) (*cinfo->err->output_message) (cinfo);
  166.  
  167.  /* Return control to the setjmp point */
  168.  longjmp(setjmp_buffer, 1);
  169. }
  170.  
  171.  
  172. GLOBAL int
  173. read_JPEG_file (char *filenames[])
  174. {
  175.   /* This struct contains the JPEG decompression parameters and pointers to
  176.    * working space (which is allocated as needed by the JPEG library).
  177.    */
  178.   struct jpeg_decompress_struct cinfo;
  179.   /* We use our private extension JPEG error handler. */
  180.   struct jpeg_error_mgr jerr;
  181.   /* More stuff */
  182.   JSAMPARRAY buffer;        /* Output row buffer */
  183.   int row_stride;        /* physical row width in output buffer */
  184.   int DisplaySuccess, i;
  185.   char *filename;
  186.  
  187.   /* Step 1: allocate and initialize JPEG decompression object */
  188.   
  189.   jpeg_create_decompress(&cinfo);
  190.  
  191.   /* Now we can initialize the JPEG decompression object. */
  192.  
  193.   /* We set up the normal JPEG error routines, then override error_exit. */
  194.   cinfo.err = jpeg_std_error(&jerr);
  195.   jerr.error_exit = my_error_exit;
  196.  
  197.   /* Add some application-specific error messages (from myerror.h) */
  198.   jerr.addon_message_table = addon_message_table;
  199.   jerr.first_addon_message = JMSG_FIRSTADDONCODE;
  200.   jerr.last_addon_message = JMSG_LASTADDONCODE;
  201.  
  202.   /* main loop */
  203.  
  204.   for(PictureNr=0; PictureNr < NumPictures; PictureNr++)
  205.   {
  206.  
  207.     /* Establish the setjmp return context for my_error_exit to use. */
  208.     if (setjmp(setjmp_buffer)) {
  209.       /* If we get here, the JPEG code has signaled an error.
  210.        * We need to clean up the JPEG object, close the input file, and return.
  211.        */
  212.       if(PictureNr == NumPictures -1)
  213.         jpeg_destroy_decompress(&cinfo);
  214.       else
  215.         jpeg_abort_decompress(&cinfo);
  216.       if(infile)
  217.       {
  218.         Close(infile);
  219.         infile=0;
  220.       }
  221.       if(olddir)
  222.       {
  223.         CurrentDir(olddir);
  224.         olddir=0;
  225.       }
  226.       if(ColorCache)
  227.       {
  228.         free(ColorCache);
  229.         ColorCache=NULL;
  230.       }
  231.       if(MapFileName)
  232.       {
  233.         free(MapFileName);
  234.         MapFileName=NULL;
  235.       }
  236.       if(MapDirName)
  237.       {
  238.         free(MapDirName);
  239.         MapDirName=NULL;
  240.       }
  241.       if(ColorMapFile)
  242.       {
  243.         Close(ColorMapFile);
  244.         ColorMapFile=0;
  245.       }
  246.       if(OutputBuffer)
  247.       {
  248.        free(OutputBuffer);
  249.        OutputBuffer=NULL;
  250.       }
  251.       if(ScreenColorTable)
  252.       {
  253.         free(ScreenColorTable);
  254.         ScreenColorTable=NULL;
  255.       }
  256.       if(PictureNr == NumPictures -1 || WBFlags.SMRenable)
  257.       {
  258.         if(!ButtonPressed) FinalWait();
  259.         CloseDisplay();
  260.         if(finish) break;
  261.       }
  262.       if(finish)
  263.       {
  264.         CloseDisplay();
  265.         break;
  266.       }
  267.       else if(ButtonPressed)
  268.         DoNotWait=1;
  269.       continue;
  270.     }
  271.  
  272.     if(olddir)
  273.     {
  274.       CurrentDir(olddir);
  275.       olddir=0;
  276.     }
  277.  
  278.     ScaleFitDisplayID = 0;
  279.  
  280.     if(WBFiles) memcpy(&WBFlags, &OldFlags, sizeof(struct WBFlags));
  281.  
  282.     if(WBFiles && wb_arg)
  283.     {
  284.       if(wb_arg->wa_Name == NULL) ERREXIT(&cinfo, JERR_JPEGAGA_OPEN);
  285.       filename = wb_arg->wa_Name;
  286.       printf(" %s: ", filename);
  287.       fflush(stdout);
  288.  
  289.       if(wb_arg->wa_Lock != 0)
  290.       {
  291.         olddir = CurrentDir(wb_arg->wa_Lock);
  292.         infile = Open(filename, MODE_OLDFILE);
  293.         if(infile) ParseToolTypes(wb_arg, 0);
  294.       }
  295.       else
  296.       {
  297.         infile = Open(filename, MODE_OLDFILE);    
  298.       }
  299.       wb_arg++;
  300.     }
  301.     else if(!WBFiles)
  302.     {
  303.       filename = filenames[PictureNr];
  304.       printf(" %s: ", filename);
  305.       fflush(stdout);
  306.       infile = Open(filename, MODE_OLDFILE);
  307.     }
  308.  
  309.     if(infile == 0)
  310.     {
  311.       ERREXIT(&cinfo, JERR_JPEGAGA_OPEN);
  312.     }
  313.     
  314.     /* Step 2: specify data source (eg, a file) */
  315.  
  316.     Amiga_jpeg_stdio_src(&cinfo, infile);
  317.  
  318.     /* Step 3: read file parameters with jpeg_read_header() */
  319.  
  320.     (void) jpeg_read_header(&cinfo, TRUE);
  321.     /* We can ignore the return value from jpeg_read_header since
  322.      *   (a) suspension is not possible with the stdio data source, and
  323.      *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
  324.      * See libjpeg.doc for more info.
  325.      */
  326.  
  327.     printf("%d x %d, ", (int)cinfo.image_width, (int)cinfo.image_height);
  328.     fflush(stdout);
  329.  
  330.     /* Step 4: set parameters for decompression */
  331.  
  332.     /* set user selectable options */
  333.   
  334.     if(WBFlags.DCTFast) cinfo.dct_method = JDCT_IFAST; 
  335.  
  336.     if(WBFlags.NoSmooth) cinfo.do_fancy_upsampling = FALSE; /* override this with options */
  337.  
  338.     if(WBFlags.SMRenable)
  339.     {
  340.       int grayscale=0;
  341.       
  342.       if(cinfo.out_color_space == JCS_GRAYSCALE) grayscale = 1;
  343.       FinalWait();
  344.       CloseDisplay();
  345.       if(finish) ERREXIT(&cinfo, JWRN_JPEGAGA_STOPPED);
  346.       if(ChooseScreenMode(grayscale, filename)) ERREXIT(&cinfo, JERR_JPEGAGA_NOMODE);
  347.       if(SMR_HAM)
  348.         WBFlags.GrayEnable = 0;
  349.       else
  350.         WBFlags.GrayEnable = 1;
  351.     }
  352.     else if(WBFlags.ScaleFit)
  353.     {
  354.       int tempscale;
  355.       if(WBFlags.GrayEnable) cinfo.out_color_space=JCS_GRAYSCALE; /* force grayscale output */
  356.       if(cinfo.out_color_space != JCS_GRAYSCALE)
  357.         Mode = HAM8;
  358.       else
  359.         Mode = 0;
  360.       tempscale = FindScaleFit(cinfo.image_width, cinfo.image_height, Mode);
  361.       if(tempscale == -1) ERREXIT(&cinfo, JERR_JPEGAGA_DISPLAY);
  362.       WBFlags.scale = tempscale;
  363.     }
  364.   
  365.     if(WBFlags.GrayEnable) cinfo.out_color_space=JCS_GRAYSCALE; /* force grayscale output */
  366.     cinfo.scale_num = 1;
  367.     cinfo.scale_denom = (unsigned int)WBFlags.scale;
  368.  
  369.     if(WBFlags.scale != 1) printf("scale 1/%d, ", WBFlags.scale);
  370.  
  371.     /* Step 5: Start decompressor */
  372.  
  373.     jpeg_start_decompress(&cinfo);
  374.  
  375.     /* Now setup everything for showing the picture */
  376.  
  377.     if(cinfo.out_color_space == JCS_GRAYSCALE)
  378.     {
  379.       printf("grayscale\n");
  380.       fflush(stdout);
  381.       ScreenColorTable = malloc(256*4*3+8);
  382.       if(!ScreenColorTable) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
  383.  
  384.       for(i=0; i<256; i++)
  385.       {
  386.         ScreenColorTable[i*3+1] = (unsigned long)i<<24;
  387.         ScreenColorTable[i*3+2] = (unsigned long)i<<24;
  388.         ScreenColorTable[i*3+3] = (unsigned long)i<<24;
  389.       }
  390.  
  391.       ScreenColorTable[0] = 256L<<16+0;
  392.       ScreenColorTable[256*3+1] = 0;
  393.  
  394.       DisplaySuccess = InitDisplay(cinfo.output_width, cinfo.output_height, 0, 8);
  395.  
  396.       if(finish) ERREXIT(&cinfo, JWRN_JPEGAGA_STOPPED);
  397.  
  398.       if(ScreenColorTable)
  399.       {
  400.         free(ScreenColorTable);
  401.         ScreenColorTable=NULL;
  402.       }
  403.  
  404.       if(DisplaySuccess != 1)
  405.       {
  406.         CloseDisplay();
  407.         ERREXIT(&cinfo, JERR_JPEGAGA_DISPLAY);
  408.       }
  409.  
  410.     }
  411.     else if(cinfo.out_color_space == JCS_RGB)
  412.     {
  413.       printf("HAM8");
  414.       fflush(stdout);
  415.       ColorCache = calloc(262145, 1);
  416.       if(ColorCache == NULL) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
  417.  
  418.       /* create the multiplication table */
  419.       for(i=-255; i<256; i++) Mult_Table[i+255] = (unsigned short)(i*i);
  420.  
  421.       MapFileName = malloc(strlen(filename)+5);
  422.       if(MapFileName == NULL) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
  423.       
  424.       strcpy(MapFileName, filename); /* create a copy of the file name */
  425.  
  426.       strcat(MapFileName, ".map");
  427.  
  428.       ColorMapFile = Open(MapFileName, MODE_OLDFILE);
  429.  
  430.       /* try to find the file in the directory pointed to by the environment */
  431.       /* variable MAPDIR to support read-only devices like CD-ROM */
  432.       if(!ColorMapFile)
  433.       {
  434.         char *MapDir;
  435.         MapDir = getenv("MAPDIR");
  436.         if(MapDir)
  437.         if(strlen(MapDir) != 0)
  438.         {
  439.           int pos,i;
  440.           MapDirName = malloc(strlen(MapDir)+strlen(MapFileName)+5); /* worst case */
  441.           if(!MapDirName) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
  442.           strcpy(MapDirName, MapDir);
  443.  
  444.           i = strlen(MapDirName);
  445.           if(MapDirName[i-1] != '/' && MapDirName[i-1] != ':')
  446.           {
  447.             strcat(MapDirName, "/");
  448.             i++;
  449.           }
  450.           i = strlen(MapFileName);
  451.           while(i > 0 && MapFileName[i-1] != '/' && MapFileName[i-1] != ':') i--;
  452.           strcat(MapDirName, &MapFileName[i]);
  453.           /* printf("%s\n", MapDirName); */
  454.           ColorMapFile = Open(MapDirName, MODE_OLDFILE);
  455.         }
  456.       }
  457.  
  458.  
  459.       if(!ColorMapFile)
  460.       {
  461.         int i = strlen(MapFileName) - 4;
  462.         while(i > 0 && MapFileName[i-1] != '.') i--;
  463.         if(MapFileName[i-1] == '.')
  464.         {
  465.           strcpy(&MapFileName[i], "map");
  466.           ColorMapFile = Open(MapFileName, MODE_OLDFILE);
  467.         }
  468.       }
  469.  
  470.  
  471.       if(ColorMapFile)
  472.       {
  473.         unsigned short MagicNumber;
  474.         unsigned int Reserved;
  475.  
  476.         if(Read(ColorMapFile, &MagicNumber, 2) != 2) ERREXIT(&cinfo, JERR_JPEGAGA_MAPFILE);
  477.         if(MagicNumber != 0x1203) ERREXIT(&cinfo, JERR_JPEGAGA_MAPFILE);  
  478.         if(Read(ColorMapFile, &Reserved, 4) != 4) ERREXIT(&cinfo, JERR_JPEGAGA_MAPFILE);
  479.         if(Read(ColorMapFile, ColorTable,  64*3) != 64*3) ERREXIT(&cinfo, JERR_JPEGAGA_MAPFILE);
  480.  
  481.         printf(" with mapfile\n");
  482.         Close(ColorMapFile);
  483.  
  484.         ColorMapFile = 0;
  485.       }
  486.       else
  487.       {
  488.         printf(", create a colormap file for better quality!\n");
  489.         memcpy(ColorTable, FixedColorTable, 64*3);
  490.       }
  491.  
  492.       if(MapFileName)
  493.       {
  494.         free(MapFileName);
  495.         MapFileName=NULL;
  496.       }
  497.       if(MapDirName)
  498.       {
  499.         free(MapDirName);
  500.         MapDirName=NULL;
  501.       }
  502.  
  503.       ScreenColorTable = malloc(64*4*3+8);
  504.       if(!ScreenColorTable) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
  505.  
  506.       for(i=0; i<64; i++)
  507.       {
  508.         ScreenColorTable[i*3+1] = (unsigned long)ColorTable[i*3+1]<<26; 
  509.         ScreenColorTable[i*3+2] = (unsigned long)ColorTable[i*3+2]<<26;
  510.         ScreenColorTable[i*3+3] = (unsigned long)ColorTable[i*3]<<26;
  511.       }
  512.  
  513.       ScreenColorTable[0] = 64L<<16+0;
  514.       ScreenColorTable[64*3+1] = 0;
  515.  
  516.       DisplaySuccess = InitDisplay(cinfo.output_width, cinfo.output_height, HAM8, 8);
  517.       
  518.       if(finish) ERREXIT(&cinfo, JWRN_JPEGAGA_STOPPED);
  519.        
  520.       if(ScreenColorTable)
  521.       {
  522.         free(ScreenColorTable);
  523.         ScreenColorTable=NULL;
  524.       }
  525.  
  526.       if(DisplaySuccess != 1)
  527.       {
  528.         CloseDisplay();
  529.         ERREXIT(&cinfo, JERR_JPEGAGA_DISPLAY);
  530.       }
  531.     }
  532.     else ERREXIT(&cinfo, JERR_CONVERSION_NOTIMPL); 
  533.  
  534.     /* JSAMPLEs per row in output buffer */
  535.     /* make it a bit larger to allow direct screen output */
  536.  
  537.     row_stride = (((cinfo.output_width * cinfo.output_components +15)>>4)<<4);
  538.  
  539.     /* Make a sample array that will go away when done with image */
  540.     buffer = (*cinfo.mem->alloc_sarray)
  541.           ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, cinfo.rec_outbuf_height);
  542.  
  543.     /* printf("Recommended size: %d\n", cinfo.rec_outbuf_height); */
  544.  
  545.     /* Step 6: while (scan lines remain to be read) */
  546.     /*           jpeg_read_scanlines(...); */
  547.  
  548.     /* Here we use the library's state variable cinfo.output_scanline as the
  549.      * loop counter, so that we don't have to keep track ourselves.
  550.      */
  551.  
  552.     ButtonPressed=0;
  553.  
  554.     if(cinfo.out_color_space == JCS_GRAYSCALE)
  555.     {
  556.       JDIMENSION numpixels, i;
  557.       while (cinfo.output_scanline < cinfo.output_height)
  558.       {
  559.         numpixels = jpeg_read_scanlines(&cinfo, buffer, cinfo.rec_outbuf_height);
  560.         if(CheckButton())
  561.         {
  562.           ButtonPressed=1;
  563.           ERREXIT(&cinfo, JWRN_JPEGAGA_STOPPED);
  564.         }
  565.         /* Assume put_scanline_someplace wants a pointer and sample count. */
  566.         for(i=0; i<numpixels; i++)
  567.           DisplayRow(buffer[i], cinfo.output_width);
  568.       }
  569.     }
  570.  
  571.     else if(cinfo.out_color_space == JCS_RGB)
  572.     {
  573.       JDIMENSION numpixels, i;
  574. #ifdef DEBUGFILE
  575.       FILE *testfile;
  576.       testfile = fopen("test.ppm", "w");
  577.       if(testfile == NULL) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
  578.       fprintf(testfile, "P6\n%ld %ld\n%d\n",
  579.           (long) cinfo.output_width, (long) cinfo.output_height, 255);
  580. #endif
  581.  
  582.       OutputBuffer = malloc(((cinfo.output_width+15)>>4)<<4);
  583.       if(!OutputBuffer) ERREXIT(&cinfo, JERR_JPEGAGA_MEMORY);
  584.     
  585.     
  586.       while (cinfo.output_scanline < cinfo.output_height)
  587.       {
  588.         numpixels = jpeg_read_scanlines(&cinfo, buffer, cinfo.rec_outbuf_height);
  589.         if(CheckButton())
  590.         {
  591.           ButtonPressed=1;
  592.           ERREXIT(&cinfo, JWRN_JPEGAGA_STOPPED);
  593.         }
  594.         /* Assume put_scanline_someplace wants a pointer and sample count. */
  595.         for(i=0; i<numpixels; i++)
  596.         {
  597. #ifdef DEBUGFILE
  598.           fwrite(buffer[i], 3, cinfo.output_width, testfile);
  599. #endif
  600.           EncodeHAM8(buffer[i], OutputBuffer, cinfo.output_width);
  601.           DisplayRow(OutputBuffer, cinfo.output_width);
  602.         }
  603.       }
  604. #ifdef DEBUGFILE
  605.       fclose(testfile);
  606. #endif
  607.       free(OutputBuffer);
  608.       OutputBuffer = NULL;
  609.     }
  610.  
  611.  
  612.     /* Step 7: Finish decompression */
  613.   
  614.     (void) jpeg_finish_decompress(&cinfo);
  615.     /* We can ignore the return value since suspension is not possible
  616.      * with the stdio data source.
  617.      */
  618.  
  619.     /* Step 8: Release JPEG decompression object */
  620.  
  621.     /* This is an important step since it will release a good deal of memory. */
  622.     if(PictureNr == NumPictures -1) jpeg_destroy_decompress(&cinfo);
  623.  
  624.     /* After finish_decompress, we can close the input file.
  625.      * Here we postpone it until after no more JPEG errors are possible,
  626.      * so as to simplify the setjmp error logic above.  (Actually, I don't
  627.      * think that jpeg_destroy can do an error exit, but why assume anything...)
  628.      */
  629.     if(olddir)
  630.     {
  631.       CurrentDir(olddir);
  632.       olddir=0;
  633.     }
  634.     if(infile)
  635.     {
  636.       Close(infile);
  637.       infile=0;
  638.     }
  639.     if(ColorCache)
  640.     {
  641.       free(ColorCache);
  642.       ColorCache=NULL;
  643.     }
  644.  
  645.     DoNotWait=0;
  646.     if(PictureNr == NumPictures -1)
  647.     {
  648.       FinalWait();
  649.       CloseDisplay();
  650.     }
  651.     if(finish) break;
  652.  
  653.     /* At this point you may want to check to see whether any corrupt-data
  654.      * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
  655.      */
  656.  
  657.     /* And we're done! */
  658.   }
  659.   CloseDisplay(); /* just for the case we forgot to close something */
  660.   return 0;
  661. }
  662.  
  663.  
  664. static void Usage(void)
  665. {
  666.  printf("Usage: jpegAGA [switches] [files]\n"
  667.         "switches: -gray      force grayscale output\n"
  668.         "          -fit       scale output to fit on the screen\n"
  669.         "          -scale M/N scale output image by fraction M/N, eg, 1/8\n"
  670.         "          -nosmooth  don't use high quality upsampling\n"
  671.         "          -dct fast  use fast integer DCT (less accurate)\n"
  672.         "          -vga       use VGA screenmode\n"
  673.         "          -super72   use SUPER72 mode for large pictures\n"
  674.         "          -smr       use screen mode requester\n");
  675.  CloseDisplay();
  676.  exit(10);
  677. }
  678.  
  679. int main(int argc, char *argv[])
  680. {
  681.  int i;
  682. #ifdef __GNUC__
  683.  signal(SIGINT, SIG_IGN); /* disable CTRL-C handling */
  684. #endif
  685.  printf("jpegAGA 2.1 by Günther Röhrich. This program is Public Domain.\n");
  686.  
  687.  /* remove the comments for beta versions */
  688.  /* printf("Preliminary version. DO NOT SPREAD IT!\n"); */
  689.  
  690.  if(argc == 0 && argv) FillWB(argv);
  691.  
  692.  else for(i=1; i<argc; i++)
  693.  {
  694.    if(MYSTRNCMP(argv[i], "-", 1))
  695.    {
  696.      FillNameBuffer(argv[i]);
  697.      continue;
  698.    }
  699.    #ifndef __GNUC__
  700.    strupr(argv[i]);
  701.    #endif
  702.    if(!MYSTRNCMP(argv[i], "-GRAY", 5)) WBFlags.GrayEnable=1;   
  703.  
  704.    else if(!MYSTRNCMP(argv[i], "-VGA", 4)) WBFlags.VGAenable=1;
  705.  
  706.    else if(!MYSTRNCMP(argv[i], "-SUPER72", 8)) WBFlags.SUPER72enable=1;
  707.  
  708.    else if(!MYSTRNCMP(argv[i], "-SMR", 4)) WBFlags.SMRenable=1;
  709.  
  710.    else if(!MYSTRNCMP(argv[i], "-NOSMOOTH", 9)) WBFlags.NoSmooth=1;
  711.  
  712.    else if(!MYSTRNCMP(argv[i], "-FIT", 4)) WBFlags.ScaleFit=1;
  713.  
  714.    else if(!MYSTRNCMP(argv[i], "-DCT", 4))
  715.    {
  716.      if(argc == i+1) Usage(); /* last argument */
  717.      i++;
  718.       if(!MYSTRNCMP(argv[i], "FAST", 3)) WBFlags.DCTFast=1;
  719.       else if(!MYSTRNCMP(argv[i], "INT", 3)) WBFlags.DCTFast=0;
  720.    }
  721.  
  722.    else if(!MYSTRNCMP(argv[i], "-SCALE", 6))
  723.    {
  724.      if(argc == i+1) Usage(); /* last argument */
  725.      i++;
  726.       if(!MYSTRNCMP(argv[i], "1/1", 3)) WBFlags.scale=1;
  727.       else if(!MYSTRNCMP(argv[i], "1/2", 3)) WBFlags.scale=2;
  728.       else if(!MYSTRNCMP(argv[i], "1/4", 3)) WBFlags.scale=4;
  729.       else if(!MYSTRNCMP(argv[i], "1/8", 3)) WBFlags.scale=8;
  730.       else Usage();
  731.    }
  732.      
  733.    else Usage();
  734.  }    
  735.  
  736.  if(NumPictures == 0) ChooseFiles();
  737.  
  738.  if(NumPictures == 0)
  739.  {
  740.    CloseDisplay();
  741.    exit(10);
  742.  }
  743.  
  744.  read_JPEG_file(PicArray);
  745.  return 0;
  746. }
  747.